import { Injectable, Logger } from '@nestjs/common';
import * as puppeteer from 'puppeteer';
import {
  ICrawler,
  NovelInfo,
  ChapterInfo,
  ChapterContent,
} from '../interfaces/crawler.interface';

export interface QidianChapterInfo {
  title: string;
  url: string;
  index: number;
  isFree: boolean;
  content?: string;
  volumeName: string;
}

@Injectable()
export class QidianCrawler implements ICrawler {
  private readonly logger = new Logger(QidianCrawler.name);
  private browser: puppeteer.Browser;

  async initBrowser() {
    if (!this.browser) {
      const executablePath =
        process.env.CHROME_EXECUTABLE_PATH ||
        'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe';

      this.browser = await puppeteer.launch({
        headless: true,
        executablePath,
        args: [
          '--no-sandbox',
          '--disable-setuid-sandbox',
          '--disable-web-security',
        ],
      });
    }
  }

  getSource(): string {
    return 'qidian';
  }

  validateUrl(url: string): boolean {
    return url.includes('qidian.com');
  }

  async getNovelInfo(url: string): Promise<NovelInfo> {
    await this.initBrowser();
    const page = await this.browser.newPage();

    try {
      await page.setUserAgent(
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
      );
      await page.goto(url, { waitUntil: 'networkidle2' });

      // 等待页面加载完成，增加等待时间以应对动态加载
      await new Promise((resolve) => setTimeout(resolve, 8000));

      // 先检查页面是否有内容，用于调试
      const pageTitle = await page.title();
      this.logger.log(`页面标题: ${pageTitle}`);

      const novelInfo = await page.evaluate(() => {
        // 获取小说基本信息 - 扩展选择器以匹配起点实际页面结构
        let title = '';
        let author = '';
        let cover = '';
        let description = '';
        let category = '';
        let wordCount = '';
        let status = 0;
        let updateTime = '';

        // 获取书名 - 使用更广泛的选择器
        const titleSelectors = [
          '.book-info__title',
          'h1.book-name',
          '.book-name',
          'h1',
          '.title',
          '[class*="title"]',
          '.info-title',
          '.lib-name',
          '.main-title',
          'h1[class*="title"]',
          'h1[class*="name"]',
          '.book-title',
        ];

        for (const selector of titleSelectors) {
          const titleElement = document.querySelector(selector);
          if (titleElement) {
            title = titleElement.textContent?.trim() || '';
            if (title) break;
          }
        }

        // 获取作者 - 使用更广泛的选择器
        const authorSelectors = [
          '.book-info__author__name',
          '.author',
          '.book-author',
          '[class*="author"]',
          '.writer',
          '.author-name',
          '.book-writer',
          'span[class*="author"]',
          '.name',
          '.creator',
        ];

        for (const selector of authorSelectors) {
          const authorElement = document.querySelector(selector);
          if (authorElement) {
            author = authorElement.textContent?.trim() || '';
            // 清理作者信息，去除"作者："等前缀
            author = author.replace(/^作者[:：]\s*/, '').trim();
            if (author) break;
          }
        }

        // 获取封面
        const coverSelectors = [
          '.book-img__img',
          'img[src*="cover"]',
          '.cover img',
          '.book-cover img',
          'img[alt*="封面"]',
          '.book-img img',
          'img[class*="cover"]',
          '.pic img',
          '.book-pic img',
        ];

        for (const selector of coverSelectors) {
          const coverElement = document.querySelector(selector);
          if (coverElement) {
            cover =
              coverElement.getAttribute('src') ||
              coverElement.getAttribute('data-src') ||
              '';
            if (cover) break;
          }
        }

        // 获取分类
        const categorySelectors = [
          '.book-info__tag',
          '.tag',
          '[class*="category"]',
          '.book-category',
          '.type',
        ];

        for (const selector of categorySelectors) {
          const categoryElement = document.querySelector(selector);
          if (categoryElement) {
            category = categoryElement.textContent?.trim() || '';
            if (category) break;
          }
        }

        // 获取状态和字数 - 从详细信息中提取
        const detailSelectors = [
          '.book-info__row',
          '.book-info-detail',
          '.book-detail',
          '.info-detail',
        ];

        for (const selector of detailSelectors) {
          const detailContainer = document.querySelector(selector);
          if (detailContainer) {
            const detailTexts =
              detailContainer.querySelectorAll('span, div, li');
            detailTexts.forEach((element) => {
              const text = element.textContent?.trim();
              if (!text) return;

              // 状态
              if (text.includes('连载') || text.includes('完结')) {
                status = text.includes('完结') ? 1 : 0;
              }

              // 字数
              if (text.includes('万字') || text.includes('字')) {
                wordCount = text;
              }

              // 更新时间
              if (
                text.match(/\d{4}-\d{2}-\d{2}/) ||
                text.includes('更新于') ||
                text.includes('更新时间')
              ) {
                updateTime = text;
              }
            });
          }
        }

        // 获取简介
        const descSelectors = [
          '.book-info__intro',
          '.description',
          '.intro',
          '[class*="intro"]',
          '.book-desc',
          '.summary',
        ];

        for (const selector of descSelectors) {
          const descElement = document.querySelector(selector);
          if (descElement) {
            description = descElement.textContent?.trim() || '';
            if (description && description.length > 20) break;
          }
        }

        // 获取章节列表和卷信息
        const chapterList: QidianChapterInfo[] = [];

        // 查找目录按钮
        const catalogSelectors = [
          'a[href*="catalog"]',
          'a[href*="chapter"]',
          '[class*="catalog"]',
          '[class*="chapter"]',
          '.read-btn',
        ];

        let catalogUrl: string | null = null;
        for (const selector of catalogSelectors) {
          const catalogElement = document.querySelector(selector);
          if (catalogElement) {
            const href = catalogElement.getAttribute('href');
            if (href) {
              catalogUrl = href.startsWith('http')
                ? href
                : `https://www.qidian.com${href}`;
              break;
            }
          }
        }

        // 如果已经在目录页面，尝试解析章节
        if (
          window.location.href.includes('catalog') ||
          window.location.href.includes('chapter')
        ) {
          const volumeSelectors = [
            '.volume-wrap',
            '.volume',
            '[class*="volume"]',
            '.catalog-volume',
          ];

          for (const volumeSelector of volumeSelectors) {
            const volumeElements = document.querySelectorAll(volumeSelector);

            volumeElements.forEach((volumeElement, volumeIndex) => {
              const volumeNameElement = volumeElement.querySelector(
                '.volume-name, [class*="volume-name"]',
              );
              const volumeName =
                volumeNameElement?.textContent?.trim() ||
                `第${volumeIndex + 1}卷`;

              const chapterSelectors = [
                '[class*="chapter"]',
                '.chapter-item',
                'a[href*="chapter"]',
                '.catalog-chapter',
              ];

              for (const chapterSelector of chapterSelectors) {
                const chapterElements =
                  volumeElement.querySelectorAll(chapterSelector);

                chapterElements.forEach((chapterElement, chapterIndex) => {
                  const linkElement =
                    chapterElement.querySelector('a') || chapterElement;
                  const title = linkElement?.textContent?.trim() || '';
                  const href =
                    linkElement?.getAttribute('href') ||
                    chapterElement?.getAttribute('href') ||
                    '';

                  // 判断是否为免费章节
                  const isFree =
                    !chapterElement.querySelector(
                      '[class*="vip"], [class*="lock"], .vip-icon, .lock',
                    ) &&
                    !title.includes('VIP') &&
                    !title.includes('付费');

                  if (title && href) {
                    const fullUrl = href.startsWith('http')
                      ? href
                      : `https://www.qidian.com${href}`;
                    chapterList.push({
                      title,
                      url: fullUrl,
                      index: chapterList.length + 1,
                      isFree,
                      volumeName,
                      content: undefined,
                    });
                  }
                });
              }
            });
          }
        }

        return {
          title,
          author,
          cover,
          description,
          category,
          wordCount,
          status,
          updateTime,
          chapterList: chapterList.map((chapter) => ({
            title: chapter.title,
            url: chapter.url,
            index: chapter.index,
          })),
        };
      });

      // 如果没有找到章节，尝试跳转到目录页面
      if (novelInfo.chapterList.length === 0) {
        this.logger.log('未在当前页面找到章节，尝试跳转到目录页面');

        // 先尝试直接跳转到起点目录页面
        const bookId = url.match(/\/(\d+)/)?.[1];
        if (bookId) {
          const catalogUrl = `https://www.qidian.com/book/${bookId}/catalog`;
          await page.goto(catalogUrl, { waitUntil: 'networkidle2' });
          await new Promise((resolve) => setTimeout(resolve, 3000));
        } else {
          await this.navigateToCatalog(page, url);
        }

        // 重新解析章节
        const chapters = await page.evaluate(() => {
          const chapterList: QidianChapterInfo[] = [];
          const volumeSelectors = [
            '.volume-wrap',
            '.volume',
            '[class*="volume"]',
            '.catalog-volume',
          ];

          for (const volumeSelector of volumeSelectors) {
            const volumeElements = document.querySelectorAll(volumeSelector);

            volumeElements.forEach((volumeElement, volumeIndex) => {
              const volumeNameElement = volumeElement.querySelector(
                '.volume-name, [class*="volume-name"]',
              );
              const volumeName =
                volumeNameElement?.textContent?.trim() ||
                `第${volumeIndex + 1}卷`;

              const chapterSelectors = [
                '[class*="chapter"]',
                '.chapter-item',
                'a[href*="chapter"]',
                '.catalog-chapter',
              ];

              for (const chapterSelector of chapterSelectors) {
                const chapterElements =
                  volumeElement.querySelectorAll(chapterSelector);

                chapterElements.forEach((chapterElement, chapterIndex) => {
                  const linkElement =
                    chapterElement.querySelector('a') || chapterElement;
                  const title = linkElement?.textContent?.trim() || '';
                  const href =
                    linkElement?.getAttribute('href') ||
                    chapterElement?.getAttribute('href') ||
                    '';

                  // 判断是否为免费章节
                  const isFree =
                    !chapterElement.querySelector(
                      '[class*="vip"], [class*="lock"], .vip-icon, .lock',
                    ) &&
                    !title.includes('VIP') &&
                    !title.includes('付费');

                  if (title && href) {
                    const fullUrl = href.startsWith('http')
                      ? href
                      : `https://www.qidian.com${href}`;
                    chapterList.push({
                      title,
                      url: fullUrl,
                      index: chapterList.length + 1,
                      isFree,
                      volumeName,
                      content: undefined,
                    });
                  }
                });
              }
            });
          }

          return chapterList;
        });

        novelInfo.chapterList = chapters.map((chapter) => ({
          title: chapter.title,
          url: chapter.url,
          index: chapter.index,
        }));
      }

      this.logger.log(
        `起点小说解析完成: 标题="${novelInfo.title}", 作者="${novelInfo.author}", 章节数=${novelInfo.chapterList.length}`,
      );
      return novelInfo;
    } finally {
      await page.close();
    }
  }

  async getChapterContent(chapterUrl: string): Promise<ChapterContent> {
    await this.initBrowser();
    const page = await this.browser.newPage();

    try {
      await page.setUserAgent(
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
      );
      await page.goto(chapterUrl, { waitUntil: 'networkidle2' });

      const chapterContent = await page.evaluate(() => {
        // 获取章节标题
        const title =
          document
            .querySelector('.chapter-title, h1, .title')
            ?.textContent?.trim() || '';

        // 获取章节内容
        const contentElement =
          document.querySelector(
            '.chapter-content, .content, [class*="content"]',
          ) || document.querySelector('.text-content, .read-content');

        let content = contentElement?.textContent?.trim() || '';

        // 检查是否为VIP章节
        const isVip =
          document.querySelector('.vip-content, .vip-tip, [class*="vip"]') !==
          null;

        if (isVip) {
          content = '【VIP章节，需要付费订阅才能阅读完整内容】';
        }

        return {
          title,
          content,
          index: 0,
        };
      });

      return chapterContent;
    } finally {
      await page.close();
    }
  }

  /**
   * 获取详细的章节信息，包括收费状态和内容
   */
  async getDetailedChapterList(
    catalogUrl: string,
  ): Promise<QidianChapterInfo[]> {
    await this.initBrowser();
    const page = await this.browser.newPage();

    try {
      await page.setUserAgent(
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
      );
      await page.goto(catalogUrl, { waitUntil: 'networkidle2' });

      const chapters = await page.evaluate(() => {
        const chapterList: QidianChapterInfo[] = [];
        const volumeElements = document.querySelectorAll(
          '[class*="volume"], .volume-wrap, .volume',
        );

        volumeElements.forEach((volumeElement, volumeIndex) => {
          const volumeName =
            volumeElement
              .querySelector('.volume-name, [class*="volume-name"]')
              ?.textContent?.trim() || `第${volumeIndex + 1}卷`;

          const chapterElements = volumeElement.querySelectorAll(
            '[class*="chapter"], .chapter-item, a[href*="chapter"]',
          );

          chapterElements.forEach((chapterElement, chapterIndex) => {
            const linkElement =
              chapterElement.querySelector('a') || chapterElement;
            const title = linkElement?.textContent?.trim() || '';
            const href =
              linkElement?.getAttribute('href') ||
              chapterElement?.getAttribute('href') ||
              '';

            // 判断是否为免费章节
            const isFree =
              !chapterElement.querySelector(
                '[class*="vip"], [class*="lock"], .vip-icon, .lock',
              ) &&
              !title.includes('VIP') &&
              !title.includes('付费');

            if (title && href) {
              const fullUrl = href.startsWith('http')
                ? href
                : `https://www.qidian.com${href}`;
              chapterList.push({
                title,
                url: fullUrl,
                index: chapterList.length + 1,
                isFree,
                volumeName,
                content: undefined,
              });
            }
          });
        });

        return chapterList;
      });

      // 为免费章节获取内容
      for (const chapter of chapters) {
        if (chapter.isFree) {
          try {
            const chapterContent = await this.getChapterContent(chapter.url);
            chapter.content = chapterContent.content;
            this.logger.log(`获取免费章节内容: ${chapter.title}`);

            // 避免请求过于频繁
            await new Promise((resolve) => setTimeout(resolve, 1000));
          } catch (error) {
            this.logger.warn(
              `获取章节内容失败: ${chapter.title}, ${error.message}`,
            );
            chapter.content = '获取内容失败';
          }
        }
      }

      return chapters;
    } finally {
      await page.close();
    }
  }

  private async navigateToCatalog(
    page: puppeteer.Page,
    currentUrl: string,
  ): Promise<void> {
    try {
      // 尝试查找并点击目录按钮
      const catalogSelectors = [
        '[class*="catalog"]',
        '[class*="chapter"]',
        'a[href*="catalog"]',
        'a[href*="chapter"]',
        '.book-info__action .catalog',
      ];

      for (const selector of catalogSelectors) {
        const element = await page.$(selector);
        if (element) {
          await element.click();
          await page.waitForNavigation({ waitUntil: 'networkidle2' });
          await new Promise((resolve) => setTimeout(resolve, 3000));
          break;
        }
      }
    } catch (error) {
      this.logger.warn('跳转到目录页面失败:', error.message);
    }
  }

  async onModuleDestroy() {
    if (this.browser) {
      await this.browser.close();
    }
  }
}
